#pragma once

#include "iostream"
#include "vector"
#include "algorithm"

using namespace std;

/*HJJ QQ479287006
 *给定一个二叉树

struct Node {
  int val;
  Node *left;
  Node *right;
  Node *next;
}
填充它的每个 next 指针，让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点，则将 next 指针设置为 NULL。

初始状态下，所有 next 指针都被设置为 NULL。

 

进阶：

你只能使用常量级额外空间。
使用递归解题也符合要求，本题中递归程序占用的栈空间不算做额外的空间复杂度。
 输入：root = [1,2,3,4,5,null,7]
输出：[1,#,2,3,#,4,5,7,#]
解释：给定二叉树如图 A 所示，你的函数应该填充它的每个 next 指针，以指向其下一个右侧节点，如图 B 所示。序列化输出按层序遍历顺序（由 next 指针连接），'#' 表示每层的末尾。
来源：力扣（LeetCode）
链接：https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * */


class Node {
public:
    int val;
    Node *left;
    Node *right;
    Node *next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node *_left, Node *_right, Node *_next)
            : val(_val), left(_left), right(_right), next(_next) {}
};

//首先这个层次遍历肯定可以 这个跟上一个题差距在 完全不完全
//递归返回填充后的头结点
Node *getNextNode(Node *root) {
    if (!root)
        return root;

    if (root->left)
        return root->left;
    if (root->right)
        return root->right;
    if (root->next)
        return getNextNode(root->next);

    return nullptr;

}

Node *connect(Node *root) {

    if (!root)
        return root;

    if (root->left)
        root->left->next = getNextNode(root);


    if (root->right)
        root->right->next = getNextNode(root);

    connect(root->left);
    connect(root->right);
    return root;//其实这个root 就是头不用想太多 因为你开头就是头节点 递归调用也没经过root=root->next 这种肯定是返回头了

}

Node *connect(Node *root) {

    if (!root)
        return root;

    if (root->left && root->right)
        root->left->next = root->right;
    else if (root->left && root->next) {
        //若父亲的下一个不空 先寻找他的左子树 若不存在再寻找他的右子树
        Node *temp = root;
        //如果next 不空且 他的左右子树全为空 则继续循环
        while (root->next) {
            if (root->next->left) {
                temp->left->next = root->next->left;
                break;
            } else if (root->next->right) {
                temp->left->next = root->next->right;
                break;
            }

            root = root->next;
        }

        root = temp;

    }

    Node *temp = root;
    //如果右边的左右都为 null
    while (temp->right && root->next) {
        if (root->next->left) {
            temp->right->next = root->next->left;
            break;
        } else if (root->next->right) {
            temp->right->next = root->next->right;
            break;
        }

        root = root->next;
    }
    root = temp;//恢复环境

    connect(root->right);//一直有个用例卡着不动
    connect(root->left);//一定要 先right 后right 我擦。。。。。自己想想 TODO 没有链接在一起右边的
    return root;//其实这个root 就是头不用想太多 因为你开头就是头节点 递归调用也没经过root=root->next 这种肯定是返回头了

}